
/**
 * @constructor
 * @extends NodeList
 * @param {number} areaWidth
 * @param {number} areaHeight
 * @returns {NodeOpenList}
 */
function NodeOpenList(areaWidth, areaHeight) {
	
	/**
	 * cached Node with lowest F value
	 * @private
	 */
	var lowestFNode = null;
	
	NodeList.call(this, areaWidth, areaHeight);
};

NodeOpenList.prototype = Object.create(NodeList.prototype);
NodeOpenList.prototype.constructor = NodeOpenList;

/**
 * @public
 * @memberOf NodeOpenList.prototype
 * @param {Node} n
 */
NodeOpenList.prototype.add = function(n) {
	if(n!=null && this.nodePositionHash[n.x][n.y]==null) {
		this.size++;
	}
	this.nodePositionHash[n.x][n.y] = n;
	
	if(this.lowestFNode == null) {
		this.lowestFNode = n;
	} else if (n==null) {
		this.lowestFNode = n;
	} else {
		if(n.getF() < this.lowestFNode.getF()) {
			this.lowestFNode = n;
		}
	}	
};

/**
 * @public
 * @memberOf NodeOpenList.prototype
 * @param {Number} x
 * @param {Number} y
 */
NodeOpenList.prototype.remove = function(x, y) {
	if(this.size==0) {
		this.lowestFNode = null;
		return;
	}
	var existingN = this.nodePositionHash[x][y];
	if(existingN==null) {
		if(this.lowestFNode != null && this.lowestFNode.x == x && this.lowestFNode.y == y) {
			this.lowestFNode = this.calculateLowestFNode();
		}
		return;
	}
	this.nodePositionHash[x][y] = null;	
	this.size--;
	if(this.lowestFNode != null && this.lowestFNode.x == x && this.lowestFNode.y == y) {
		this.lowestFNode = this.calculateLowestFNode();
	}
};
		
/**
 * @public
 * @memberOf NodeOpenList.prototype
 * @returns {Node}
 */
NodeOpenList.prototype.getLowestFNode = function() {
	if(this.nodePositionHash.length == 0) {
		return null;
	}
	
	return this.lowestFNode;
};

/**
 * @private
 */
NodeOpenList.prototype.calculateLowestFNode = function() {
	if(this.nodePositionHash.length == 0) {
		return null;
	}
	
	var lowestFNode = null; 
	for(var x=0; x<this.nodePositionHash.length; x++) {
		var column = this.nodePositionHash[x];
		if(column!=null) {
			for(var y=0; y<column.length; y++) {
				var n = column[y];
				if(n!=null) {
					if(lowestFNode==null) {
						lowestFNode=n;
					} else {
						if(n.getF()<lowestFNode.getF()) {
							lowestFNode = n;
						}
					}
				}
			}
		}
	}
	return lowestFNode;
};